<template>
	<view>
		<zero-loading v-if="loading" type="circle" :mask="true" :maskOpacity="0.8"></zero-loading>
		
		
		<view class="content"  @touchstart="hideDrawer">

			<scroll-view class="msg-list" :class="popupLayerClass" scroll-y="true"
				:scroll-with-animation="scrollAnimation" :scroll-top="scrollTop" :scroll-into-view="scrollToView"
				upper-threshold="50" enable-back-to-top="true" :refresher-enabled='refresherEnabled' @scroll='roll'
				:refresher-triggered="triggered" refresher-background="#e5e5e5" @refresherpulling="onPulling"
				@refresherrefresh="onRefresh" @refresherrestore="onRestore">
				
				 <u-notice-bar color="#333333" text="急重症患者不适合网上诊疗/咨询，请立即前往当地医院急诊。" style="position: fixed;width: 100%;z-index: 999999;left: 50%;transform: translateX(-50%);"></u-notice-bar>

				<!-- 加载历史数据waitingUI -->
				<!-- <view class="loading">
					<view class="spinner">
						<view class="rect1"></view>
						<view class="rect2"></view>
						<view class="rect3"></view>
						<view class="rect4"></view>
						<view class="rect5"></view>
					</view>
				</view> -->

				<view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.id">
					<!-- 系统消息 -->
					<!-- <block>
						<view class="system">
							<view  class="text">
								欢迎咨询
							</view>

						</view>
					</block> -->
					<!-- 用户消息 -->
					<block>
						<!-- 自己发出的消息 -->
						<view class="my" v-if="row.fromUserId==currentId">
							<!-- 左-消息 -->
							<view class="left">
								<!-- 文字消息 -->
								<view class="bubble" v-if="row.msgType==1">
									<rich-text :nodes="row.msgContent"></rich-text>
								</view>
								<!-- 语音消息 -->
								<view v-if="row.msgType==2" class="bubble voice" @tap="playVoice(row)"
									:class="playMsgid == row.id?'play':''">
									<view class="length">{{row.l}}</view>
									<view class="icon my-voice"></view>
								</view>
								<!-- 图片消息 -->
								<view v-if="row.msgType==3" class="bubble img" @tap="showPic(row.msgContent)">
									<u--image :showLoading="true" :lazy-load="true" :src="row.msgContent" :width="row.w"
										:height="row.h">
										<template v-slot:loading>
											<u-loading-icon color="red"></u-loading-icon>
										</template>
									</u--image>

									<!-- <image lazy-load :src="row.msgContent" :style="{'width': row.w+'px','height': row.h+'px'}">
									</image> -->

								</view>

							</view>
							<!-- 右-头像 -->
							<view class="right">
								<!-- <image src="../static/image/patient.jpg"></image> -->
								<u-avatar src="../static/image/man.png"></u-avatar>
							</view>
						</view>
						<!-- 别人发出的消息 -->
						<view class="other" v-else>
							<!-- 左-头像 -->
							<view class="left">
								<!-- <image src="../static/image/doctor.jpg"></image> -->
								<u-avatar src="../static/image/doctor.jpg"></u-avatar>
							</view>
							<!-- 右-用户名称-时间-消息 -->
							<view class="right">
								<view class="username">
									<view class="name">{{row.realName}}</view>
									<view class="time">{{row.createTime}}</view>
								</view>
								<!-- 文字消息 -->
								<view v-if="row.msgType==1" class="bubble">
									<rich-text :nodes="row.msgContent"></rich-text>
								</view>
								<!-- 语音消息 -->
								<view v-if="row.msgType==2" class="bubble voice" @tap="playVoice(row)"
									:class="playMsgid == row.id?'play':''">
									<view class="icon other-voice"></view>
									<view class="length">{{row.l}}</view>
								</view>
								<!-- 图片消息 -->
								<view v-if="row.msgType==3" class="bubble img" @tap="showPic(row.msgContent)">
									<!-- <image lazy-load :src="row.msgContent" :style="{'width': row.w+'px','height': row.h+'px'}">
									</image> -->
									<u--image :showLoading="true" :lazy-load="true" :src="row.msgContent" :width="row.w"
										:height="row.h">
										<template v-slot:loading>
											<u-loading-icon color="red"></u-loading-icon>
										</template>
									</u--image>
								</view>

							</view>
						</view>
					</block>
				</view>

			</scroll-view>
		</view>
		<!-- 抽屉栏 -->
		<view class="popup-layer" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<!-- 表情 -->
			<swiper class="emoji-swiper" :class="{hidden:hideEmoji}" indicator-dots="true" duration="150">
				<swiper-item v-for="(page,pid) in emojiList" :key="pid">
					<view v-for="(em,eid) in page" :key="eid" @tap="addEmoji(em)">
						<!-- https://zhoukaiwen.com/img/icon/emojj1/1.png -->
						<!-- <image mode="widthFix" :src="'https://me.qaqavr.com/emoji/'+em.url"></image> -->
						<u--image :lazyLoad="true" :fade="true" duration="450" width="8.4vw" height="8.4vw"
							mode="widthFix" :src="'https://me.qaqavr.com/emoji/'+em.url">
							<template v-slot:loading>
								<u-loading-icon color="red"></u-loading-icon>
							</template>
						</u--image>
					</view>
				</swiper-item>
			</swiper>
			<!-- 更多功能 相册-拍照-红包 -->
			<view class="more-layer" :class="{hidden:hideMore}">
				<view class="list">
					<view class="box" @tap="chooseImage">
						<view class="icon tupian2"></view>
					</view>
					<view class="box" @tap="camera">
						<view class="icon paizhao"></view>
					</view>
				</view>
			</view>
		</view>

		<!-- 底部输入栏 -->
		<view class="input-box cu-bar tabbar" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<!-- H5下不能录音，输入栏布局改动一下 -->
			<!-- #ifndef H5 -->
			<view class="voice">
				<view class="icon" :class="isVoice?'jianpan':'yuyin'" @tap="switchVoice"></view>
			</view>
			<!-- #endif -->
			<!-- #ifdef H5 -->
			<view class="more" @tap="showMore">
				<view class="icon add"></view>
			</view>
			<!-- #endif -->
			<view class="textbox">
				<view class="voice-mode" :class="[isVoice?'':'hidden',recording?'recording':'']"
					@touchstart="voiceBegin" @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd"
					@touchcancel="voiceCancel">{{voiceTis}}</view>
				<view class="text-mode" :class="isVoice?'hidden':''">
					<view class="box">
						<textarea auto-height="true" v-model="textMsg" @focus="textareaFocus" />
					</view>
					<view class="em" @tap="chooseEmoji">
						<view class="icon biaoqing"></view>
					</view>
				</view>
			</view>
			<!-- #ifndef H5 -->
			<view class="more" @tap="showMore">
				<view class="icon add"></view>
			</view>
			<!-- #endif -->
			<view class="send" :class="isVoice?'hidden':''" @tap="sendText">
				<view class="btn">发送</view>
			</view>
		</view>
		<!-- 录音UI效果 -->
		<view class="record" :class="recording?'':'hidden'">
			<view class="ing" :class="willStop?'hidden':''">
				<view class="icon luyin2"></view>
			</view>
			<view class="cancel" :class="willStop?'':'hidden'">
				<view class="icon chehui"></view>
			</view>
			<view class="tis" :class="willStop?'change':''">{{recordTis}}</view>
		</view>

	</view>
</template>
<script>
	import emoji from '../common/emoji.js'
	import onlineEmoji from '../common/onlineEmoji.js'
	//模拟聊天记录，实际应该查询数据库
	// import chat from '../common/chatMsgList.js'
	export default {
		data() {
			return {
				triggered: false, //开启下拉刷新
				refresherEnabled: false, //开启自定义下拉刷新
				loading: true,
				//文字消息
				textMsg: '',
				//消息列表
				isHistoryLoading: false,
				scrollAnimation: false,
				scrollTop: 0,
				scrollToView: '',
				msgList: [],
				msgImgList: [],

				//录音相关参数
				// #ifndef H5
				//H5不能录音
				RECORDER: uni.getRecorderManager(),
				// #endif
				isVoice: false,
				voiceTis: '按住 说话',
				recordTis: "手指上滑 取消发送",
				recording: false,
				willStop: false,
				initPoint: {
					identifier: 0,
					Y: 0
				},
				recordTimer: null,
				recordLength: 0,

				//播放语音相关参数
				AUDIO: uni.createInnerAudioContext(),
				playMsgid: null,
				VoiceTimer: null,
				// 抽屉参数
				popupLayerClass: '',
				// more参数
				hideMore: true,
				//表情定义
				hideEmoji: true,
				emojiList: emoji.emojiList,
				//表情图片图床名称 ，由于我上传的第三方图床名称会有改变，所以有此数据来做对应，您实际应用中应该不需要
				onlineEmoji: onlineEmoji.onlineEmojiList,
				currentId: this.$store.state.user, //当前用户id
				pageObj: {
					toUserId: null,
					pageIndex: 1,
					pageSize: 20
				},
				chatName: null,
				clientName:null
			};
		},
		beforeDestroy() {
			if(this.AUDIO){
				this.AUDIO.stop()
			}
		},
		watch: {
			"$store.state.websocketData"(val, oldval) {
				if (Number(val.fromUserId)==Number(this.pageObj.toUserId)){
					val.createTime = this.formatDateTimeForHMS(val.createTime)
					val.realName = this.chatName
					this.msgList.push(val) //需要比较一下是否是当前用户消息
					this.$nextTick(() => {
						// 滚动到底
						this.scrollToView = 'msg' + val.id
					})
					//重置未读状态待处理
					this.resetReadStatus()
				}
			}
		},
		onLoad(option) {
			this.pageObj.toUserId = option.userId
			this.chatName = option.name
			this.clientName = option.clientName
			//语音自然播放结束
			this.AUDIO.onEnded((res) => {
				this.playMsgid = null;
			});
			// #ifndef H5
			//录音开始事件
			this.RECORDER.onStart((e) => {
				this.recordBegin(e);
			})
			//录音结束事件
			this.RECORDER.onStop((e) => {
				this.recordEnd(e);
			})
			// #endif
			//设置title
			uni.setNavigationBarTitle({
				title: this.chatName
			})

		},
		onShow() {

		},
		onReady() {
			this.initMsg()
		},
		methods: {
			// 监听下拉
			onPulling(e) {

			},
			//重置未读消息
			resetReadStatus() {
				uni.request({
					url: uni.$http.baseUrl + '/chatMessage/resetReadStatus?userId=' + this.pageObj.toUserId,
					header: {
						token: uni.getStorageSync('token')
					},
					method: 'POST',
					success: (res) => {
						if (res.data.code === 200) {
							console.log('重置成功')
						} else {
							uni.showToast({
								icon:'none',
								title:res.data.message
							})
						}
					}
			
				})
			},
			//下拉刷新
			onRefresh() {
				if (this._freshing) return;
				this._freshing = true;
				//刷新初始化数据
				// this.current = 1
				//调用获取数据的函数
				this.getMsgList()
				this.triggered = 'restore';
				setTimeout(() => {
					this.triggered = false;
					this._freshing = false;
				}, 500)
			},
			// 下拉复位
			onRestore() {
				this.triggered = 'restore'; // 需要重置
			},
			// 下拉被中止
			onAbort() {
				this.triggered = false
			},
			// 获取滚动距离
			roll(res) {
				if (res.target.scrollTop >= 20) {
					this.refresherEnabled = false
				} else {
					this.refresherEnabled = true
				}
			},
			//发送websocket
			sendWebsocket(obj) {
				obj.clientName = this.clientName
				this.$store.dispatch('websocketSend', JSON.stringify(obj));
			},
			// 接受消息(筛选处理)
			screenMsg(msg) {
				//从长连接处转发给这个方法，进行筛选处理
				// 用户消息
				switch (msg.msgType) {
					case 1:
						this.addTextMsg(msg);
						break;
					case 2:
						this.addVoiceMsg(msg);
						break;
					case 3:
						this.addImgMsg(msg);
						break;
				}
				//发送websocket消息
				this.sendWebsocket(msg)

				//非自己的消息震动
				if (msg.fromUserId != this.currentId) {
					console.log('振动');
					uni.vibrateLong();
				}
				this.$nextTick(()=>{
					// 滚动到底
					this.scrollToView = 'msg' + msg.id
				})
			},
			
			 formatDateTimeForHMS(obj) {
			    if (obj == null) {
			        return null
			    }
			    let date = new Date(obj);
			    let m = "0" + (date.getMonth() + 1);
			    let d = "0" + date.getDate();
			    let h = "0" + date.getHours();
			    let mm = "0" + date.getMinutes();
			    let s = date.getSeconds();
			    return m.substring(m.length - 2, m.length) + "-" + d.substring(d.length - 2, d.length) + " " + h.substring(h.length - 2, h.length) + ":" + mm.substring(mm.length - 2, mm.length);
			},

			//初始化加载消息
			initMsg() {
				// 加载初始页面消息
				this.pageObj.pageIndex = 1
				uni.request({
					url: uni.$http.baseUrl + '/chatMessage/findToOne',
					data: this.pageObj,
					header: {
						token: uni.getStorageSync('token')
					},
					method: 'POST',
					success: (res) => {
						this.pageObj.pageIndex = 2
						if (res.data.code === 200) {
							let list = res.data.data
							if (list && list.length != 0) {
								for (let i = 0; i < list.length; i++) {
									if (list[i].msgType == 3) {
										list[i] = this.setPicSize(list[i]);
										this.msgImgList.push(list[i].msgContent);
									}
								}
								this.msgList = list
								// 滚动到底部
								this.$nextTick(()=>{
									this.scrollTop = 9999999;
									this.$nextTick(function() {
										this.scrollAnimation = true;
										// 滚动到底
										this.scrollToView = 'msg' + this.msgList[this.msgList
												.length -
												1]
											.id
									});
								})
							}

							this.loading = false
						} else {
							this.loading = false
						}
					}

				})

			},

			// 加载初始页面消息
			getMsgList() {
				uni.$http.post('/chatMessage/findToOne', this.pageObj).then(res => {
					if (res.data.code === 200) {
						let list = res.data.data
						if (list && list.length != 0) {
							this.pageObj.pageIndex = this.pageObj.pageIndex + 1
							for (let i = 0; i < list.length; i++) {
								if (list[i].msgType == 3) {
									list[i] = this.setPicSize(list[i]);
									this.msgImgList.push(list[i].msgContent);
								}
							}
							this.msgList = list.concat(this.msgList)

						}

						if (this.msgList.length == 0) {
							return false
						}

						// 滚动到底部
						this.$nextTick(()=>{
							//进入页面滚动到底部
							this.scrollTop = 9999999;
							this.$nextTick(function() {
								this.scrollAnimation = true;
								// 滚动到底
								this.scrollToView = 'msg' + this.msgList[this.msgList.length - 1]
									.id
							});
						})
					}
				})
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(content) {
				// 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
				let maxW = uni.upx2px(350); //350是定义消息图片最大宽度
				let maxH = uni.upx2px(350); //350是定义消息图片最大高度
				if (content.w > maxW || content.h > maxH) {
					let scale = content.w / content.h;
					content.w = scale > 1 ? maxW : maxH * scale;
					content.h = scale > 1 ? maxW / scale : maxH;
				}
				return content;
			},

			//更多功能(点击+弹出) 
			showMore() {
				this.isVoice = false;
				this.hideEmoji = true;
				if (this.hideMore) {
					this.hideMore = false;
					this.openDrawer();
				} else {
					this.hideDrawer();
				}
			},
			// 打开抽屉
			openDrawer() {
				this.popupLayerClass = 'showLayer';
			},
			// 隐藏抽屉
			hideDrawer() {
				this.popupLayerClass = '';
				setTimeout(() => {
					this.hideMore = true;
					this.hideEmoji = true;
				}, 150);
			},
			// 选择图片发送
			chooseImage() {
				this.getImage('album');
			},
			//拍照发送
			camera() {
				this.getImage('camera');
			},

			//选照片 or 拍照
			getImage(type) {
				this.hideDrawer();
				uni.chooseImage({
					count: 1, // 最多可以选择的图片张数，默认9
					sourceType: [type],
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					success: (res) => {
						uni.showLoading({
							title: '上传中...',
						})
						uni.getImageInfo({
							src: res.tempFilePaths[0],
							success: (image) => {
								let msg = {
									msgContent: res.tempFilePaths[0],
									w: image.width,
									h: image.height
								};
								let that = this
								uni.uploadFile({
									url: uni.$http.baseUrl + '/system/uploadFile',
									header: {
										token: uni.getStorageSync('token')
									},
									filePath: msg.msgContent,
									name: 'file',
									success(uploadFileRes) {
										const photores = JSON.parse(uploadFileRes.data);
										if (photores.code === 200) {
											msg.msgContent = photores.data;
											that.sendMsg(msg, 3);
											uni.hideLoading()
										} else {
											uni.hideLoading()
										}

									}
								});

							}
						});

					}
				});
			},
			// 选择表情
			chooseEmoji() {
				this.hideMore = true;
				if (this.hideEmoji) {
					this.hideEmoji = false;
					this.openDrawer();
				} else {
					this.hideDrawer();
				}
			},
			//添加表情
			addEmoji(em) {
				this.textMsg += em.alt;
			},

			//获取焦点，如果不是选表情ing,则关闭抽屉
			textareaFocus() {
				if (this.popupLayerClass == 'showLayer' && this.hideMore == false) {
					this.hideDrawer();
				}
			},
			// 发送文字消息
			sendText() {
				this.hideDrawer(); //隐藏抽屉
				if (!this.textMsg) {
					return;
				}
				let content = this.replaceEmoji(this.textMsg);
				let msg = {
					msgContent: content
				}
				this.sendMsg(msg, 1);
				this.textMsg = ''; //清空输入框
			},
			//替换表情符号为图片
			replaceEmoji(str) {
				let replacedStr = str.replace(/\[([^(\]|\[)]*)\]/g, (item, index) => {

					console.log("str: " + str);
					console.log("index: " + index);
					console.log("item: " + item);

					for (let i = 0; i < this.emojiList.length; i++) {
						let row = this.emojiList[i];
						for (let j = 0; j < row.length; j++) {
							let EM = row[j];
							if (EM.alt == item) {
								//在线表情路径，图文混排必须使用网络路径，请上传一份表情到你的服务器后再替换此路径 
								//比如你上传服务器后，你的100.gif路径为https://www.xxx.com/emoji/100.gif 则替换onlinePath填写为https://www.xxx.com/emoji/
								let onlinePath = 'https://me.qaqavr.com/emoji/'
								let imgstr = '<img width="32rpx" src="' + onlinePath + this.onlineEmoji[EM.url] +
									'">';
								console.log("imgstr: " + imgstr);
								return imgstr;
							}
						}
					}
				});
				return '<div style="display: flex;align-items: center;word-wrap:break-word;">' + replacedStr + '</div>';
			},

			// 发送消息
			sendMsg(content, type) {
				//实际应用中，此处应该提交长连接，模板仅做本地处理。
				var nowDate = new Date();
				let lastid
				if (this.msgList.length === 0) {
					lastid = 1
				} else {
					lastid = this.msgList[this.msgList.length - 1].id;
					lastid++;
				}
				let msg = {
					id: lastid,
					createTime: nowDate,
					msgType: type,
					fromUserId: this.currentId,
					toUserId: this.pageObj.toUserId,
					msgContent: content.msgContent,
					realName: null,
					h: content.h,
					w: content.w,
					l: content.l
				}
				// 发送消息
				this.screenMsg(msg);

			},

			// 添加文字消息到列表
			addTextMsg(msg) {
				this.msgList.push(msg);
			},
			// 添加语音消息到列表
			addVoiceMsg(msg) {
				this.msgList.push(msg);
			},
			// 添加图片消息到列表
			addImgMsg(msg) {
				msg = this.setPicSize(msg);
				this.msgImgList.push(msg.msgContent);
				this.msgList.push(msg);
			},
			addRedEnvelopeMsg(msg) {
				this.msgList.push(msg);
			},
			// 添加系统文字消息到列表
			addSystemTextMsg(msg) {
				this.msgList.push(msg);
			},

			sendSystemMsg(content, type) {
				let lastid = this.msgList[this.msgList.length - 1].msg.id;
				lastid++;
				let row = {
					type: "system",
					msg: {
						id: lastid,
						type: type,
						content: content
					}
				};
				this.screenMsg(row)
			},

			// 预览图片
			showPic(msg) {
				uni.previewImage({
					indicator: "none",
					current: msg,
					urls: this.msgImgList
				});
			},
			// 播放语音
			playVoice(msg) {
				this.playMsgid = msg.id;
				this.AUDIO.src = msg.msgContent;
				this.$nextTick(()=>{
					this.AUDIO.play();
				})
			},
			// 录音开始
			voiceBegin(e) {
				if (e.touches.length > 1) {
					return;
				}
				this.initPoint.Y = e.touches[0].clientY;
				this.initPoint.identifier = e.touches[0].identifier;
				this.RECORDER.start({
					format: "mp3"
				}); //录音开始,
			},
			//录音开始UI效果
			recordBegin(e) {
				this.recording = true;
				this.voiceTis = '松开 结束';
				this.recordLength = 0;
				this.recordTimer = setInterval(() => {
					this.recordLength++;
				}, 1000)
			},
			// 录音被打断
			voiceCancel() {
				this.recording = false;
				this.voiceTis = '按住 说话';
				this.recordTis = '手指上滑 取消发送'
				this.willStop = true; //不发送录音
				this.RECORDER.stop(); //录音结束
			},
			// 录音中(判断是否触发上滑取消发送)
			voiceIng(e) {
				if (!this.recording) {
					return;
				}
				let touche = e.touches[0];
				//上滑一个导航栏的高度触发上滑取消发送
				if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {
					this.willStop = true;
					this.recordTis = '松开手指 取消发送'
				} else {
					this.willStop = false;
					this.recordTis = '手指上滑 取消发送'
				}
			},
			// 结束录音
			voiceEnd(e) {
				if (!this.recording) {
					return;
				}
				this.recording = false;
				this.voiceTis = '按住 说话';
				this.recordTis = '手指上滑 取消发送'
				this.RECORDER.stop(); //录音结束
			},
			//录音结束(回调文件)
			recordEnd(e) {
				clearInterval(this.recordTimer);
				if (!this.willStop) {
					let msg = {
						l: null,
						msgContent: e.tempFilePath
					}
					let min = parseInt(this.recordLength / 60);
					let sec = this.recordLength % 60;
					min = min < 10 ? '0' + min : min;
					sec = sec < 10 ? '0' + sec : sec;
					msg.l = min + ':' + sec;

					let that = this
					uni.uploadFile({
						url: uni.$http.baseUrl + '/system/uploadFile',
						header: {
							token: uni.getStorageSync('token')
						},
						filePath: msg.msgContent,
						name: 'file',
						success(uploadFileRes) {
							const photores = JSON.parse(uploadFileRes.data);
							if (photores.code === 200) {
								msg.msgContent = photores.data;
								that.sendMsg(msg, 2);
								uni.hideLoading()
							} else {
								uni.hideLoading()
							}

						}
					});

				} else {
					console.log('取消发送录音');
				}
				this.willStop = false;
			},
			// 切换语音/文字输入
			switchVoice() {
				this.hideDrawer();
				this.isVoice = this.isVoice ? false : true;
			},
			discard() {
				return;
			}
		}
	}
</script>
<style lang="scss">
	@import "@/static/css/style.scss";

	.content .showLayer {
		transform: translate3d(0, -43vw, 0);
	}
	
</style>